﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SourceStatTool
{
    public partial class Form1 : Form
    {
        private int totalFiles = 0, totalLines = 0, requireLine = 0, lineNum = 0;
        public Form1()
        {
            InitializeComponent();
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            toolStripStatusLabel1.Text = "加载中。。。";
            //TreeNode rootNode = new TreeNode("我的电脑",IconIndexes.MyComputer, IconIndexes.MyComputer);  //载入显示 选择显示  
            TreeNode rootNode = new TreeNode("我的电脑");
            rootNode.Tag = "我的电脑";                            //树节点数据  
            rootNode.Text = "我的电脑";                           //树节点标签内容  
            dirTree.Nodes.Add(rootNode);               //树中添加根目录  
            foreach (string drive in Environment.GetLogicalDrives())
            {
                //实例化DriveInfo对象 命名空间System.IO  
                var dir = new DriveInfo(drive);
                switch (dir.DriveType)           //判断驱动器类型  
                {
                    case DriveType.Fixed:        //仅取固定磁盘盘符 Removable-U盘   
                        {
                            //Split仅获取盘符字母  
                            TreeNode tNode = new TreeNode(dir.Name.Split(':')[0]);
                            tNode.Name = dir.Name;
                            tNode.Tag = tNode.Name;
                            //tNode.ImageIndex = IconIndexes.FixedDrive;         //获取结点显示图片  
                            //tNode.SelectedImageIndex = IconIndexes.FixedDrive; //选择显示图片  
                            rootNode.Nodes.Add(tNode);
                            //dirTree.Nodes.Add(tNode);                    //加载驱动节点  
                            tNode.Nodes.Add("");
                        }
                        break;
                }
            }
           rootNode.Expand();                  //展开树状视图  
           toolStripStatusLabel1.Text = "";
        }

        private void dirTree_AfterExpand(object sender, TreeViewEventArgs e)
        {
            e.Node.Expand();  
        }

        private void dirTree_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            TreeViewItems.Add(e.Node); 
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            Cursor oldCursor = this.Cursor;
            this.Cursor = Cursors.WaitCursor;
            //1.获取总的选中的文件夹数量：已经展开的直接计算
            toolStripStatusLabel2.Text = "   正在统计文件夹... ";
            this.Refresh();
            List<String> dirList = getALlChecked(dirTree.Nodes);
            int folderNumber = dirList.Count;
            toolStripStatusLabel1.Text = "" + folderNumber + "个文件夹";

            //2.获取总的文件数据 
            toolStripStatusLabel2.Text = "   正在分析文件... ";
            this.Refresh();

            totalFiles = 0;
            totalLines = 0;
            lineNum = 0;
            if (int.TryParse(tbStartNum.Text, out  lineNum))
            {
                lineNum--;
            }
            List<String> contentList = processAllDirectory(dirList);
            tbContent.Lines = contentList.ToArray();
            
            toolStripStatusLabel1.Text = "" + folderNumber + "个文件夹," + totalFiles + "个文件,共"+totalLines+"行";
            toolStripStatusLabel2.Text = "";
            this.Cursor = oldCursor;
        }
        List<String> processAllDirectory(List<String> ADirList)
        {
            List<String> retList = new List<string>();
           
            Int32.TryParse(tbLines.Text, out requireLine);
            if (String.IsNullOrWhiteSpace(tbFileTypes.Text))
            {
                tbFileTypes.Text = "*";
            }
            String[] fileTypesArray=tbFileTypes.Text.Replace(" ","").Split(',');
            foreach (String dirname in ADirList)
            {
                DirectoryInfo d = new DirectoryInfo(dirname);
                foreach (String fileType in fileTypesArray)
                {
                    FileInfo[] fileArray = d.GetFiles(fileType, SearchOption.TopDirectoryOnly);
                    totalFiles += fileArray.Count();
                    foreach (FileInfo fileInfo in fileArray)
                    {
                        retList.AddRange(processOneFile(fileInfo));
                    }
                }
            }
            return retList;
        }
        List<String> processOneFile(FileInfo fileInfo)
        {
            List<String> retList = new List<string>();
            String[] content=File.ReadAllLines(fileInfo.FullName);
            //totalLines += content.Count();
            Boolean continueRemark = false, isAddLine = lineNum <= requireLine;
            foreach (String line in content)
            {
                String newline = Regex.Replace(line, "//.*|/\\*.*\\*/", "");
                //注释、空行、连续注释
                if (newline.Contains("/*"))
                {
                    continueRemark = true;
                    continue;
                }
                if (continueRemark && newline.Contains("*/"))
                {
                    continueRemark = false;
                    continue;
                }
                if (continueRemark)
                {
                    continue;
                }
                if (!String.IsNullOrWhiteSpace(newline))
                {
                    totalLines++;
                    if (isAddLine)
                    {
                        lineNum++;
                        if (cbLineNum.Checked)
                        {
                            retList.Add("" + lineNum + ":" + newline);
                        }
                        else
                        {
                            retList.Add(newline);
                        }
                    }
                }
                
            }
            return retList;
        }
        List<String> getALlChecked(TreeNodeCollection nodes)
        {
            List<String> retList= new List<String>();
            foreach(TreeNode tn in nodes){
                if (tn.Checked)
                {
                    retList.Add(tn.Name);
                    //未展开时，直接在磁盘上查找已经选中目录的子目录
                    if (tn.IsExpanded==false){
                        //递归查找子目录
                        retList.AddRange(getAllChildDirection(tn.Name));
                    }
                }
                //已经展开，肯有子节点，则对子节点进行递归判断
                if (tn.Nodes != null && tn.Nodes.Count > 0 && tn.Nodes[0].Text != "")
                {
                    retList.AddRange(getALlChecked(tn.Nodes));
                }
            }
            return retList;
        }

        List<String> getAllChildDirection(String APath)
        {
            List<String> retList = new List<String>();
            string[] ss = Directory.GetDirectories(APath, "*", SearchOption.AllDirectories);
            retList.AddRange(ss.ToList());
            return retList;
        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged_1(object sender, EventArgs e)
        {

        }

        private void cbLineNum_Click(object sender, EventArgs e)
        {
            // tbLines.Enabled = cbLineNum.Checked;
            tbStartNum.Enabled = cbLineNum.Checked;
        }

        private void cbLineNum_CheckedChanged(object sender, EventArgs e)
        {

        }
    }
    /// <summary>  
    /// 自定义类TreeViewItems 调用其Add(TreeNode e)方法加载子目录  
    /// </summary>  
    public static class TreeViewItems
    {
        public static void Add(TreeNode e)
        {
            //try..catch异常处理  
            try
            {
                //判断"我的电脑"Tag 上面加载的该结点没指定其路径  
                if (e.Tag.ToString() != "我的电脑")
                {
                    e.Nodes.Clear();                               //清除空节点再加载子节点  
                    TreeNode tNode = e;                            //获取选中\展开\折叠结点  
                    string path = tNode.Name;                      //路径    


                    //获取指定目录中的子目录名称并加载结点  
                    string[] dics = Directory.GetDirectories(path);
                    foreach (string dic in dics)
                    {
                        TreeNode subNode = new TreeNode(new DirectoryInfo(dic).Name); //实例化  
                        subNode.Name = new DirectoryInfo(dic).FullName;               //完整目录  
                        subNode.Tag = subNode.Name;
                        //subNode.ImageIndex = IconIndexes.ClosedFolder;       //获取节点显示图片  
                        //subNode.SelectedImageIndex = IconIndexes.OpenFolder; //选择节点显示图片  
                        tNode.Nodes.Add(subNode);
                        subNode.Nodes.Add("");                               //加载空节点 实现+号  
                    }
                }
            }
            catch (Exception msg)
            {
                MessageBox.Show(msg.Message);                   //异常处理  
            }
        }
    }  
}
